package org.dreamwork.jasmine2.engine;

import org.dreamwork.misc.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by IntelliJ IDEA.
 * User: seth
 * Date: 2009-2-4
 * Time: 10:38:08
 */
public class ViewStateManager extends HashMap implements IStateManager {
    private transient boolean tracing;

    private transient static final Logger logger = LoggerFactory.getLogger (ViewStateManager.class);

    public boolean isTrackingViewState () {
        return tracing;
    }

    public void loadViewState (Object savedState) throws IOException {
        byte[] buff = Base64.decode ((String) savedState);
        ByteArrayInputStream bais = new ByteArrayInputStream (buff);
        ObjectInputStream ois = new ObjectInputStream (bais);
        try {
            Map map = (Map) ois.readObject ();
            putAll (map);
        } catch (ClassNotFoundException ex) {
            logger.warn (ex.getMessage (), ex);
        } finally {
            ois.close ();
        }
    }

    public Object saveViewState () throws IOException {
        if (size () == 0) return null;
        ByteArrayOutputStream baos = new ByteArrayOutputStream ();
        ObjectOutputStream oos = new ObjectOutputStream (baos);
        oos.writeObject (this);
        oos.flush ();
        oos.close ();
        return new String (Base64.encode (baos.toByteArray ()));
    }

    public void trackViewState () {
        tracing = true;
    }

    public void stopTrackViewState () {
        tracing = false;
    }

    @SuppressWarnings ("unchecked")
    public void putAll (Map m) {
        if (!tracing)
            super.putAll (m);
        else
            throw new IllegalStateException ("Can't put value into viewstat when tracking state");
    }

    @SuppressWarnings ("unchecked")
    public Object put (Object key, Object value) {
        if (tracing)
            throw new IllegalStateException ("Can't put value into viewstat when tracking state");
        return super.put (key, value);
    }

    public Object remove (Object key) {
        if (tracing)
            throw new IllegalStateException ("Can't remove value from viewstat when tracking state");
        return super.remove (key);
    }

    public void clear () {
        if (tracing)
            throw new IllegalStateException ("Can't clear viewstat when tracking state");
        super.clear ();
    }
}